#!/bin/bash
#
# Quick way to generate a random password for online systems
#
# Usage: quickpass -l [LENGTH], where:
# length - the desired length of the password
#
# FIXME:
# because of the way `printf' is implemented (at least in bash), there's a 
# pitfall when sampling the backslash '\' character: we cannot ignore it.
# Either we interpret it and risk breaking the line when copying to xsel or we
# forcefully escape it together with every other shell character, thus 
# lengthening the passwords unpredictably. I chose the former.
#
# License information:
#
#    Copyright (C) 2016 - kzimmermann <https://quitter.se/kzimmermann>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Some online services put a cap on how long a password can be. We default it
# to 32 characters, but you can change it accordingly. If you estipulate a 
# number as an argument to this program, this value is overriden
# It's not recommended to use a password that's shorter than 14 characters!
LENGTH=32

# Do we want to use quickpass as part of a script? If so, print the password to
# stdout, where it can be piped to variable or file. Pass -p to enable it.
FORCE_PRINT=false

# Get command-line options:

while [[ -n "$1" ]]
do
    case "$1" in
        "-h" | "--help" )
        cat <<EOF
Quick way to generate a random throwaway password for online systems

Usage: $(basename $0) -l LENGTH -p, where:
-l: make a password of the desired LENGTH (default: $LENGTH)
-p: print final password to stdout (useful in shell scripts)

EOF
        exit 0
        ;;
        "-l" | "--length" ) 
            shift
            LENGTH="$1"
        ;;
        "-p" | "--print" )
            FORCE_PRINT=true
        ;;
        * ) 
            echo "Error: unrecognized option '$1'"
            exit 1
        ;;
    esac

    # call next round
    shift
done

seed="$(dd if=/dev/urandom bs=512 count=1 2> /dev/null | tr -dc [:graph:])"
index=${RANDOM:2:2}
# I need to do this to avoid things like 09, 04, etc
[[ ${index:0:1} == "0" ]] && index=${index:1:1} 
password=${seed:$index:$LENGTH}

if [[ $FORCE_PRINT == true ]]
then
    echo $password
    exit 0
fi
if [[ -f /usr/bin/xsel ]]; then
    printf %b ${password} | xsel -ib
    printf %b ${password} | xsel -i
    echo "Password copied to the clipboard."
else
    echo $password
fi
